package xin.marcher.wind.process.service.impl;

import cn.hutool.core.lang.Assert;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xin.marcher.framework.common.exception.BusinessException;
import xin.marcher.framework.common.exception.GlobalCodeEnum;
import xin.marcher.wind.process.dao.TradePlatformProcessDAO;
import xin.marcher.wind.process.dao.TradePlatformProcessNodeDAO;
import xin.marcher.wind.process.dao.TradePlatformProcessNodeImplDAO;
import xin.marcher.wind.process.domain.entity.TradePlatformProcessDO;
import xin.marcher.wind.process.domain.entity.TradePlatformProcessNodeDO;
import xin.marcher.wind.process.domain.entity.TradePlatformProcessNodeImplDO;
import xin.marcher.wind.process.domain.request.TradePlatformProcessNodeImplRequest;
import xin.marcher.wind.process.domain.request.TradePlatformProcessNodeRequest;
import xin.marcher.wind.process.domain.vo.TradePlatformProcessNodeImplVO;
import xin.marcher.wind.process.domain.vo.TradePlatformProcessNodeVO;
import xin.marcher.wind.process.service.TradePlatformProcessNodeService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @version 1.0
 */
@Service
public class TradePlatformProcessNodeServiceImpl implements TradePlatformProcessNodeService {

    @Resource
    private TradePlatformProcessDAO tradePlatformProcessDAO;

    @Resource
    private TradePlatformProcessNodeDAO tradePlatformProcessNodeDAO;

    @Resource
    private TradePlatformProcessNodeImplDAO tradePlatformProcessNodeImplDAO;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TradePlatformProcessNodeVO addProcessNode(TradePlatformProcessNodeRequest tradePlatformProcessNodeRequest) {
        Assert.notNull(tradePlatformProcessNodeRequest, "请求入参不能为空");
        Long processId = tradePlatformProcessNodeRequest.getProcessId();
        String name = tradePlatformProcessNodeRequest.getName();
        String showName = tradePlatformProcessNodeRequest.getShowName();

        Assert.notNull(processId, "流程ID不能为空");
        Assert.notNull(name, "流程节点名称不能为空");
        Assert.notNull(showName, "流程节点描述不能为空");

        // 验证processId是否存在
        TradePlatformProcessDO tradePlatformProcessDO = tradePlatformProcessDAO.getById(processId);
        if(tradePlatformProcessDO == null) {
            throw new BusinessException(GlobalCodeEnum.GL_SERVER_ERROR.getRealCode(), "流程ID{}不存在", processId.toString());
        }

        TradePlatformProcessNodeDO tradePlatformProcessNodeDO = new TradePlatformProcessNodeDO();
        tradePlatformProcessNodeDO.setProcessId(processId);
        tradePlatformProcessNodeDO.setName(name);
        tradePlatformProcessNodeDO.setShowName(showName);
        tradePlatformProcessNodeDAO.save(tradePlatformProcessNodeDO);

        TradePlatformProcessNodeVO tradePlatformProcessNodeVO = new TradePlatformProcessNodeVO();
        tradePlatformProcessNodeVO.setProcessId(processId);
        tradePlatformProcessNodeVO.setName(name);
        tradePlatformProcessNodeVO.setShowName(showName);
        return tradePlatformProcessNodeVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TradePlatformProcessNodeVO editProcessNode(Long id, TradePlatformProcessNodeRequest tradePlatformProcessNodeRequest) {
        Assert.notNull(id, "流程节点ID不能为空");
        Assert.notNull(tradePlatformProcessNodeRequest, "请求入参不能为空");

        TradePlatformProcessNodeDO tradePlatformProcessNodeDO = tradePlatformProcessNodeDAO.getById(id);
        if(tradePlatformProcessNodeDO == null) {
            throw new BusinessException(GlobalCodeEnum.GL_SERVER_ERROR.getRealCode(), "流程节点{}不存在", id.toString());
        }

        Long processId = tradePlatformProcessNodeRequest.getProcessId();
        String name = tradePlatformProcessNodeRequest.getName();
        String showName = tradePlatformProcessNodeRequest.getShowName();

        if(processId != null) {
            // 验证processId是否存在
            TradePlatformProcessDO tradePlatformProcessDO = tradePlatformProcessDAO.getById(processId);
            if(tradePlatformProcessDO == null) {
                throw new BusinessException(GlobalCodeEnum.GL_SERVER_ERROR.getRealCode(), "流程ID{}不存在", processId.toString());
            }
            tradePlatformProcessNodeDO.setProcessId(processId);
        }

        if(StringUtils.isNotEmpty(name)) {
            tradePlatformProcessNodeDO.setName(name);
        }

        if(StringUtils.isNotEmpty(showName)) {
            tradePlatformProcessNodeDO.setShowName(showName);
        }

        tradePlatformProcessNodeDAO.updateById(tradePlatformProcessNodeDO);

        TradePlatformProcessNodeVO tradePlatformProcessNodeVO = new TradePlatformProcessNodeVO();
        tradePlatformProcessNodeVO.setProcessId(tradePlatformProcessNodeDO.getProcessId());
        tradePlatformProcessNodeVO.setName(tradePlatformProcessNodeDO.getName());
        tradePlatformProcessNodeVO.setShowName(tradePlatformProcessNodeDO.getShowName());
        return tradePlatformProcessNodeVO;
    }

    @Override
    public List<TradePlatformProcessNodeVO> listProcessNode(Long processId) {
        Assert.notNull(processId, "流程ID不能为空");

        List<TradePlatformProcessNodeDO> list = tradePlatformProcessNodeDAO.listByProcessId(processId);

        if(list != null && !list.isEmpty()) {
            List<TradePlatformProcessNodeVO> tradePlatformProcessNodeList = new ArrayList<>();
            for(TradePlatformProcessNodeDO nodeDO : list) {
                TradePlatformProcessNodeVO tradePlatformProcessNodeVO = new TradePlatformProcessNodeVO();
                tradePlatformProcessNodeVO.setProcessId(processId);
                tradePlatformProcessNodeVO.setName(nodeDO.getName());
                tradePlatformProcessNodeVO.setShowName(nodeDO.getShowName());
                tradePlatformProcessNodeList.add(tradePlatformProcessNodeVO);
            }

            return tradePlatformProcessNodeList;
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeProcessNode(Long id) {
        Assert.notNull(id, "流程节点ID不能为空");

        List<TradePlatformProcessNodeImplDO> list = tradePlatformProcessNodeImplDAO.listByProcessNodeId(id);
        if(list != null && !list.isEmpty()) {
            throw new BusinessException(GlobalCodeEnum.GL_SERVER_ERROR.getRealCode(), "流程节点{}还存在关联的节点实现，请先删除节点实现数据", id.toString());
        }

        return tradePlatformProcessNodeDAO.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TradePlatformProcessNodeImplVO addProcessNodeImpl(TradePlatformProcessNodeImplRequest tradePlatformProcessNodeImplRequest) {
        Assert.notNull(tradePlatformProcessNodeImplRequest, "请求入参不能为空");
        Long processNodeId = tradePlatformProcessNodeImplRequest.getProcessNodeId();
        String showName = tradePlatformProcessNodeImplRequest.getShowName();
        String clazzName = tradePlatformProcessNodeImplRequest.getClazzName();

        Assert.notNull(processNodeId, "流程节点ID不能为空");
        Assert.notNull(showName, "流程节点实现名称不能为空");
        Assert.notNull(clazzName, "流程节点实现类名不能为空");

        // 检查流程节点ID是否存在
        TradePlatformProcessNodeDO tradePlatformProcessNodeDO = tradePlatformProcessNodeDAO.getById(processNodeId);
        if(tradePlatformProcessNodeDO == null) {
            throw new BusinessException(GlobalCodeEnum.GL_SERVER_ERROR.getRealCode(), "流程节点{}不存在", processNodeId.toString());
        }

        TradePlatformProcessNodeImplDO tradePlatformProcessNodeImplDO = new TradePlatformProcessNodeImplDO();
        tradePlatformProcessNodeImplDO.setProcessNodeId(processNodeId);
        tradePlatformProcessNodeImplDO.setShowName(showName);
        tradePlatformProcessNodeImplDO.setClazzName(clazzName);

        tradePlatformProcessNodeImplDAO.save(tradePlatformProcessNodeImplDO);

        TradePlatformProcessNodeImplVO tradePlatformProcessNodeImplVO = new TradePlatformProcessNodeImplVO();
        tradePlatformProcessNodeImplVO.setProcessNodeId(processNodeId);
        tradePlatformProcessNodeImplVO.setProcessId(tradePlatformProcessNodeDO.getProcessId());
        tradePlatformProcessNodeImplVO.setShowName(showName);
        tradePlatformProcessNodeImplVO.setClazzName(clazzName);
        return tradePlatformProcessNodeImplVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TradePlatformProcessNodeImplVO editProcessNodeImpl(Long id, TradePlatformProcessNodeImplRequest tradePlatformProcessNodeImplRequest) {

        Assert.notNull(id, "流程节点实现ID不能为空");

        Assert.notNull(tradePlatformProcessNodeImplRequest, "请求入参不能为空");

        Long processNodeId = tradePlatformProcessNodeImplRequest.getProcessNodeId();
        String showName = tradePlatformProcessNodeImplRequest.getShowName();
        String clazzName = tradePlatformProcessNodeImplRequest.getClazzName();

        TradePlatformProcessNodeImplDO tradePlatformProcessNodeImplDO = tradePlatformProcessNodeImplDAO.getById(id);
        if(tradePlatformProcessNodeImplDO == null) {
            throw new BusinessException(GlobalCodeEnum.GL_SERVER_ERROR.getRealCode(), "流程节点实现{}不存在", id.toString());
        }

        Long processId = null;
        if(processNodeId != null) {
            // 检查流程节点ID是否存在
            TradePlatformProcessNodeDO tradePlatformProcessNodeDO = tradePlatformProcessNodeDAO.getById(processNodeId);
            if(tradePlatformProcessNodeDO == null) {
                throw new BusinessException(GlobalCodeEnum.GL_SERVER_ERROR.getRealCode(), "流程节点{}不存在", processNodeId.toString());
            }
            processId = tradePlatformProcessNodeDO.getProcessId();
            tradePlatformProcessNodeImplDO.setProcessNodeId(processNodeId);
        }

        if(StringUtils.isNotEmpty(showName)) {
            tradePlatformProcessNodeImplDO.setShowName(showName);
        }

        if(StringUtils.isNotEmpty(clazzName)) {
            tradePlatformProcessNodeImplDO.setClazzName(clazzName);
        }

        tradePlatformProcessNodeImplDAO.updateById(tradePlatformProcessNodeImplDO);

        TradePlatformProcessNodeImplVO tradePlatformProcessNodeImplVO = new TradePlatformProcessNodeImplVO();
        tradePlatformProcessNodeImplVO.setProcessNodeId(processNodeId);
        if(processId != null) {
            tradePlatformProcessNodeImplVO.setProcessId(processId);
        }
        tradePlatformProcessNodeImplVO.setShowName(showName);
        tradePlatformProcessNodeImplVO.setClazzName(clazzName);
        return tradePlatformProcessNodeImplVO;
    }

    @Override
    public List<TradePlatformProcessNodeImplVO> listProcessNodeImpl(Long processNodeId) {
        Assert.notNull(processNodeId, "流程节点实现ID不能为空");

        List<TradePlatformProcessNodeImplDO> tradePlatformProcessNodeImplList =
                tradePlatformProcessNodeImplDAO.listByProcessNodeId(processNodeId);

        if(tradePlatformProcessNodeImplList == null || tradePlatformProcessNodeImplList.isEmpty()) {
            return null;
        }

        List<TradePlatformProcessNodeImplVO> list = new ArrayList<>();
        for(TradePlatformProcessNodeImplDO nodeImplDO : tradePlatformProcessNodeImplList) {
            TradePlatformProcessNodeImplVO tradePlatformProcessNodeImplVO = new TradePlatformProcessNodeImplVO();
            tradePlatformProcessNodeImplVO.setProcessNodeId(processNodeId);
            tradePlatformProcessNodeImplVO.setShowName(nodeImplDO.getShowName());
            tradePlatformProcessNodeImplVO.setClazzName(nodeImplDO.getClazzName());

            list.add(tradePlatformProcessNodeImplVO);
        }

        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeProcessNodeImpl(Long id) {
        Assert.notNull(id, "流程节点实现ID不能为空");
        return tradePlatformProcessNodeImplDAO.removeById(id);
    }
}